<template>

  <p>{{ sum }} <button @click="sum++">sum++</button></p>
  <p>{{ fullname }} <button @click="fullname += '-'">修改姓名</button></p>
  <p>
    {{ userinfo.name }}--{{ userinfo.age }}--{{ userinfo.job.type }}--{{
      userinfo.job.salary
    }}K
    <button @click="userinfo.age++">修改年龄</button>
    <button @click="userinfo.job.salary++">修改薪水</button>

  </p>
  <p> 
    {{ userinfo.job.type }}--{{ userinfo.job.salary }}K
    <button @click="userinfo.job.type = '后端开发'">修改工作类型</button>
    <button @click="userinfo.job.salary = 30">修改薪水</button>
  </p>

</template>

<script setup>
import { ref, watch, reactive, watchEffect } from 'vue';
import { mapState } from 'vuex';
let sum = ref(0);
let fullname = ref("张三");
let userinfo = reactive({
  name: "李四",
  age: 20,
  job: {
    type: "web开发",
    salary: 20,
  },
});
//1、监听ref定义的响应式数据 immediate初始化就执行watch
watch(sum, (newvalue, oldvalue) => {
  console.log(newvalue, oldvalue);
}, { immediate: true });

//1、监听reactive 定义的响应式数据
// 注意：此处oldvalue 无效（新值与旧值一样），默认是深度监听,immediate初始化就执行watch
watch(
  userinfo,
  (newvalue, oldvalue) => {
    console.log(newvalue, oldvalue);
  },
  { immediate: true });

//1、监听mapState 定义的响应式数据
// 注意：此处oldvalue 无效（新值与旧值一样），默认是深度监听,immediate初始化就执行watch
watch(
  mapState(["count"]),
  (newvalue, oldvalue) => {
    console.log(newvalue, oldvalue);
  },
  { immediate: true });


//2、 监听ref定义的多个响应式数据,immediate初始化就执行watch
watch([sum, fullname], (newvalue, oldvalue) => {
  console.log(newvalue, oldvalue);
}, { immediate: true });

//3、 监听reactive 定义的响应式数据
// 注意：此处oldvalue 无效（新值与旧值一样），默认是深度监听,immediate初始化就执行watch
watch(
  userinfo,
  (newvalue, oldvalue) => {
    console.log(newvalue, oldvalue);
  },
  { immediate: true });


//   // watch 和 watchEffect 都能响应式地执行有副作用的回调。它们之间的主要区别是追踪响应式依赖的方式：
// watch 只追踪明确侦听的数据源。它不会追踪任何在回调中访问到的东西。另外，仅在数据源确实改变时才会触发回调。watch 会避免在发生副作用时追踪依赖，因此，我们能更加精确地控制回调函数的触发时机。

// watchEffect，则会在副作用发生期间追踪依赖。它会在同步执行过程中，自动追踪所有能访问到的响应式属性。这更方便，而且代码往往更简洁，但有时其响应性依赖关系会不那么明确。
// watchEffect举个小例子
let count = ref(0);
watchEffect(() => {
  console.log("count:", count.value);
});

setTimeout(() => {
  count.value++;
  console.log("count:", count.value);
}, 1000);

// watch 
// watch 是一个高阶函数，它接收两个参数：
// 1. 要观察的响应式数据源（可以是一个 ref、reactive 对象，也可以是一个函数，返回值也必须是响应式数据源）
// 2. 回调函数，它会在数据源发生变化时被调用。回调函数接收两个参数：
//    - 第一个参数是新值
//    - 第二个参数是旧值（仅在数据源发生变化时才有）
// watch 示例：
let count = ref(0);
watch(count, (newvalue, oldvalue) => {
  console.log("count:", newvalue, oldvalue);
});

// watchEffect 
// watchEffect 是一个函数，它接收一个回调函数作为参数，并在其内部自动追踪所有能访问到的响应式数据源。当数据源发生变化时，它会自动调用回调函数。
// watchEffect 示例：
let count = ref(0);
watchEffect(() => {
  console.log("count:", count.value);
});
setTimeout(() => {
  count.value++;
  console.log("count:", count.value);
}, 1000);





</script>

<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped>
.hello {
  text-align: center;
  margin-top: 60px;
}

h1 {
  margin: 40px 0 0;
}

button {
  margin-top: 20px;
  padding: 10px 20px;
  font-size: 16px;
  color: #fff;
  background-color: #42b983;
  border: none;
  border-radius: 5px;
  cursor: pointer;
}

button:hover {
  background-color: #4cae4c;
}
</style>